package com.airbnb.lottie;

import android.graphics.PathMeasure;
import android.graphics.PointF;
import android.support.annotation.Nullable;
import android.view.animation.Interpolator;

import java.util.List;

class PathKeyframeAnimation extends KeyframeAnimation<PointF> {
  private final PointF point = new PointF();
  private final float[] pos = new float[2];
  private final SegmentedPath segmentedPath;
  private int pathMeasureKeyframeIndex = -1;
  @Nullable private PathMeasure pathMeasure;

  PathKeyframeAnimation(long duration, LottieComposition composition, List<Float> keyTimes,
      SegmentedPath segmentedPath, List<Interpolator> interpolators) {
    super(duration, composition, keyTimes, interpolators);
    this.segmentedPath = segmentedPath;
  }

  @Override public PointF getValue() {
    if (progress <= 0f) {
      if (pathMeasureKeyframeIndex != 0 || pathMeasure == null) {
        pathMeasureKeyframeIndex = 0;
        pathMeasure = new PathMeasure(segmentedPath.getSegment(0), false);
      }
      pathMeasure.getPosTan(0, pos, null);
      point.set(pos[0], pos[1]);
      return point;
    } else if (progress >= 1f) {
      if (pathMeasureKeyframeIndex != segmentedPath.getSegmentCount() - 1 || pathMeasure == null) {
        pathMeasureKeyframeIndex = segmentedPath.getSegmentCount() - 1;
        pathMeasure =
            new PathMeasure(segmentedPath.getSegment(segmentedPath.getSegmentCount() - 1), false);
      }
      pathMeasure.getPosTan(pathMeasure.getLength(), pos, null);
      point.set(pos[0], pos[1]);
      return point;
    }

    int keyframeIndex = getKeyframeIndex();
    if (pathMeasureKeyframeIndex != keyframeIndex) {
      pathMeasureKeyframeIndex = keyframeIndex;
      pathMeasure = new PathMeasure(segmentedPath.getSegment(keyframeIndex), false);
    }

    float startKeytime = keyTimes.get(keyframeIndex);
    float endKeytime = keyTimes.get(keyframeIndex + 1);

    float percentageIntoFrame = 0;
    if (!isDiscrete) {
      percentageIntoFrame = (progress - startKeytime) / (endKeytime - startKeytime);
      if (interpolators != null) {
        percentageIntoFrame =
            interpolators.get(keyframeIndex).getInterpolation(percentageIntoFrame);
      }
    }

    pathMeasure.getPosTan(percentageIntoFrame * pathMeasure.getLength(), pos, null);
    point.set(pos[0], pos[1]);
    return point;
  }
}
